package edu.fau.scanny.stromal;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import edu.fau.scanny.r.stromal.model.*;

import org.apache.commons.collections.map.MultiKeyMap;

public class MetaFileUtils {

	private static String time = "Time", group = "Group", shortName = "Short Name", type = "Type", scalingFactor = "Scaling Factor",
			pPresent = "% Present", chip = "Chip File";

	public static MultiKeyMap createMetaFileMap(String fileName) throws IOException {
		MultiKeyMap mkMap = new MultiKeyMap();

		String thisLine;
		BufferedReader metaFile = new BufferedReader(new FileReader(fileName));
		Map<String, Integer> columnMap = headersMap(metaFile);
		while ((thisLine = metaFile.readLine()) != null) {
			String[] strar = thisLine.split("\t");
			CelFile celFile = setUpCelFile(strar, columnMap);
			List<CelFile> celFiles = new ArrayList<CelFile>();
			if (mkMap.containsKey(celFile.getTime(), celFile.getGroup(), celFile.getType())) {
				celFiles = (List<CelFile>) mkMap.get(celFile.getTime(), celFile.getGroup(), celFile.getType());
				celFiles.add(celFile);
			} else {
				celFiles.add(celFile);
				mkMap.put(celFile.getTime(), celFile.getGroup(), celFile.getType(), celFiles);
			}
		}
		return mkMap;
	}

//	public static Map<String, Map<String, List<CelFile>>> createMetaFileMap(String fileName) throws IOException {
//		String thisLine;
//		System.out.println(fileName);
//		BufferedReader metaFile = new BufferedReader(new FileReader(fileName));
//		Map<String, Map<String, List<CelFile>>> map = new HashMap<String, Map<String, List<CelFile>>>();
//		Map<String, Integer> columnMap = headersMap(metaFile);
//		while ((thisLine = metaFile.readLine()) != null) {
//			String[] strar = thisLine.split("\t");
//			CelFile celFile = setUpCelFile(strar, columnMap);
//			updateMap(map, celFile.getTime() + " " + celFile.getGroup(), celFile.getType(), celFile);
//		}
//		return map;
//	}

	private static CelFile setUpCelFile(String[] strar, Map<String, Integer> columnMap) {
		CelFile celFile = new CelFile();
		celFile.setShortName(strar[columnMap.get(shortName)]);
		celFile.setChipFile(strar[columnMap.get(chip)]);
		celFile.setScalingFactor(Double.valueOf(strar[columnMap.get(scalingFactor)]));
		celFile.setpPresent(Double.valueOf(strar[columnMap.get(pPresent)]));
		celFile.setTime(strar[columnMap.get(time)]);
		celFile.setGroup(strar[columnMap.get(group)]);
		celFile.setType(strar[columnMap.get(type)]);
		return celFile;
	}

	public static Map<String, CelFile> chipCelFileMap(String fileName) throws IOException {
		String thisLine;
		BufferedReader metaFile = new BufferedReader(new FileReader(fileName));
		Map<String, CelFile> map = new HashMap<String, CelFile>();
		Map<String, Integer> columnMap = headersMap(metaFile);
		while ((thisLine = metaFile.readLine()) != null) {
			String strar[] = thisLine.split("\t");
			CelFile celFile = setUpCelFile(strar, columnMap);
			map.put(celFile.getChipFile(), celFile);
		}
		return map;
	}

	public static Map<String, Integer> headersMap(BufferedReader metaFile) throws IOException {
		Map<String, Integer> columnMap = new HashMap<String, Integer>();
		String headers[] = metaFile.readLine().split("\t");
		for (int ii = 0; ii < headers.length; ii++) {
			columnMap.put(headers[ii], ii);
		}
		return columnMap;
	}

	// public static Map<String, String> chipGroupMap(String fileName) throws
	// IOException{
	// Map<String, String> map = stringStringMap(fileName, chip, timeGroup);
	// return map;
	// }
	//
	// public static Map<String, String> chipTypeMap(String fileName) throws
	// IOException{
	// Map<String, String> map = stringStringMap(fileName, chip, type);
	// return map;
	// }
	
	public static Map<Integer, String> orderMap(String fileName) throws IOException{
		Map<Integer, String> orderMap = new HashMap<Integer, String>();
		String thisLine;
		BufferedReader metaFile = new BufferedReader(new FileReader(fileName));
		Map<String, Integer> columnMap = headersMap(metaFile);
		while ((thisLine = metaFile.readLine()) != null) {
			String strar[] = thisLine.split("\t");
			Integer order = Integer.parseInt(strar[columnMap.get("Order")]);
			String group = strar[columnMap.get("Group")];
			orderMap.put(order, group);
		}
		return orderMap;
	}

	public static Map<String, Map<String, String>> rowColumGroupMap(String fileName, String groupName, String rowName, String columnName)
			throws IOException {
		String thisLine;
		BufferedReader metaFile = new BufferedReader(new FileReader(fileName));
		Map<String, Map<String, String>> map = new HashMap<String, Map<String, String>>();
		Map<String, Integer> columnMap = headersMap(metaFile);
		while ((thisLine = metaFile.readLine()) != null) {
			String strar[] = thisLine.split("\t");
			String row = strar[columnMap.get(rowName)];
			String column = strar[columnMap.get(columnName)];
			String group = strar[columnMap.get(groupName)];
			Map<String, String> columnGroupMap = null;
			if (map.containsKey(row)) {
				columnGroupMap = map.get(row);
				if (!columnGroupMap.containsKey(column))
					columnGroupMap.put(column, group);
			} else {
				columnGroupMap = new HashMap<String, String>();
				columnGroupMap.put(column, group);
			}
			map.put(row, columnGroupMap);
		}
		return map;
	}

	public static void updateMap(Map<String, Map<String, List<CelFile>>> map, String group, String type, CelFile cel) {
		List<CelFile> cels = null;
		Map<String, List<CelFile>> typeMap = null;
		if (map.containsKey(group)) {
			typeMap = map.get(group);
			if (typeMap.containsKey(type))
				cels = typeMap.get(type);
			else {
				cels = new ArrayList<CelFile>();
			}
		} else {
			cels = new ArrayList<CelFile>();
			typeMap = new HashMap<String, List<CelFile>>();
		}
		cels.add(cel);
		typeMap.put(type, cels);
		map.put(group, typeMap);
	}

}
